import $ from 'jquery';

let slice = Array.prototype.slice;

export default class Module {

  constructor(opts) {
    var base, instances, name;
    this.opts = Object.assign({}, this.opts, opts);
    (base = this.constructor)._connectedClasses || (base._connectedClasses = []);
    instances = this.constructor._connectedClasses.map((cls) => {
      name = cls.pluginName.charAt(0).toLowerCase() + cls.pluginName.slice(1);
      if (cls.prototype._connected) cls.prototype._module = this;
      this[name] = new cls();
      return this[name];
    });
    if (this._connected) {
      this.opts = Object.assign({}, this.opts, this._module.opts);
    } else {
      this._init();
      instances.forEach((instance) => typeof instance._init === "function" && instance._init());
    }
    this.trigger('initialized');
  }

  _init() {
  }

  on(...args) {
    $(this).on(...args);
    return this;
  }

  one(...args) {
    $(this).one(...args);
    return this;
  }

  off(...args) {
    $(this).on(...args);
    return this;
  }

  trigger(...args) {
    $(this).trigger(...args);
    return this;
  }

  triggerHandler(...args) {
    return $(this).triggerHandler(...args);
  }

  _t(...args) {
    return this.constructor._t(...args);
  }
}

Module.extend = function (obj) {
  var key, ref, val;
  if (!((obj != null) && typeof obj === 'object')) return;

  for (key in obj) {
    val = obj[key];
    if (key !== 'included' && key !== 'extended') this[key] = val;

  }
  return (ref = obj.extended) != null ? ref.call(this) : void 0;
};

Module.include = function (obj) {
  var key, ref, val;
  if (!((obj != null) && typeof obj === 'object')) return;
  for (key in obj) {
    val = obj[key];
    if (key !== 'included' && key !== 'extended') {
      this.prototype[key] = val;
    }
  }
  return (ref = obj.included) != null ? ref.call(this) : void 0;
};
Module.connect = function (cls) {
  if (typeof cls !== 'function') return;
  if (!cls.pluginName) throw new Error('Module.connect: cannot connect plugin without pluginName');
  cls.prototype._connected = true;
  if (!this._connectedClasses) this._connectedClasses = [];
  this._connectedClasses.push(cls);
  if (cls.pluginName) return this[cls.pluginName] = cls;
};
Module._t = function () {
  var args, key, ref, result;
  key = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  result = ((ref = this.i18n[this.locale]) != null ? ref[key] : void 0) || '';
  if (!(args.length > 0)) return result;
  result = result.replace(/([^%]|^)%(?:(\d+)\$)?s/g, (p0, p, position) => position ? p + args[parseInt(position) - 1] : p + args.shift());
  return result.replace(/%%s/g, '%s');
};

Module.i18n = {
  'zh-CN': {}
};

Module.locale = 'zh-CN';